home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / GraphicViewers / pCD / Source / hpcdtoppm.0.3 / hpcdtoppm.c < prev    next >
C/C++ Source or Header  |  1992-12-14  |  34KB  |  1,419 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.3
  2. *  Copyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11.  
  12. /* define OWN_WRITE either here or by compiler-option if you don't want to use
  13.    the pbmplus-routines for writing */
  14. #define xOWN_WRITE
  15.  
  16.  
  17. /* define DEBUG for some debugging informations, just remove the x from xDEBUG */
  18. #define xDEBUG
  19.  
  20. /* define MELDUNG if you want to see what is happening and what takes time,
  21.    just remove the x from xMeldung */
  22. #define xMELDUNG
  23.  
  24.  
  25.  
  26.  
  27.  
  28. #include <stdio.h>
  29.  
  30. #ifndef OWN_WRITE
  31.  
  32. #include "ppm.h"
  33.  
  34. #else
  35.  
  36. /* If the own routines are used, this is the size of the buffer in bytes.
  37.    You can shrink if needed. */
  38. #define own_BUsize 50000
  39.  
  40. /* The header for the ppm-files */
  41. #define PPM_Header "P6\n%d %d\n255\n"
  42.  
  43.  
  44. #endif
  45.  
  46.  
  47. /*
  48. ** Important: sBYTE must be a signed byte type !!!
  49. **
  50. */
  51.  
  52. #ifndef sBYTE
  53. typedef   signed char sBYTE;
  54. #endif
  55.  
  56. typedef unsigned char uBYTE;
  57. typedef unsigned long dim;
  58.  
  59. #define BaseW ((dim)768)
  60. #define BaseH ((dim)512)
  61.  
  62. #define SECSIZE 0x800
  63.  
  64.  
  65.  
  66. #define SeHead   2
  67. #define L_Head   (1+SeHead)
  68.  
  69. #define SeBase16 18
  70. #define L_Base16 (1+SeBase16)
  71.  
  72. #define SeBase4  72
  73. #define L_Base4  (1+SeBase4)
  74.  
  75. #define SeBase   288
  76. #define L_Base   (1+SeBase)
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83. enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
  84.              E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,E_IMP,E_OVSKIP,
  85.              E_TAUTO,E_TCANT };
  86.  
  87. enum TURNS  { T_NONE,T_RIGHT,T_LEFT,T_AUTO };
  88.  
  89. enum SIZES  { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_Over };
  90.  
  91. /* Default taken when no size parameter given */
  92. #define S_DEFAULT S_Base16
  93.  
  94.  
  95.  
  96.  
  97.  
  98. struct _implane
  99.  {dim  mwidth,mheight,
  100.        iwidth,iheight;
  101.   uBYTE *im;
  102.  };
  103. typedef struct _implane implane;
  104.  
  105. #define nullplane ((implane *) 0)
  106.  
  107.  
  108. static enum ERRORS readplain();
  109. static void interpolate();
  110. static void halve();
  111. static void ycctorgb();
  112. static void writepicture();
  113. static void readlpt();
  114. static void readhqt();
  115. static void decode();
  116. static void clear();
  117. static void druckeid();
  118. static void sharpit();
  119. static long Skip4Base();
  120.  
  121. static FILE *fin=0,*fout=0;
  122. static char *pcdname=0,*ppmname=0;
  123. static char nbuf[100];
  124. static uBYTE sbuffer[SECSIZE];
  125. static int do_sharp,keep_ycc;
  126.  
  127.  
  128.  
  129.  
  130. /* Using preprocessor for inline-procs */
  131. #ifdef DEBUG
  132.  
  133. static long bufpos;
  134.  
  135. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);\
  136.                   fprintf(stderr,"S-Position %x\n",ftell(fin)); }
  137. #define RPRINT  {fprintf(stderr,"R-Position %x\n",ftell(fin));}
  138.  
  139. #define READBUF   (bufpos=ftell(fin),fread(sbuffer,sizeof(sbuffer),1,fin))
  140.  
  141.  
  142. #else
  143.  
  144. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);}
  145. #define RPRINT
  146. #define READBUF   fread(sbuffer,sizeof(sbuffer),1,fin)
  147.  
  148. #endif
  149.  
  150.  
  151. #ifdef MELDUNG
  152. #define melde(x) fprintf(stderr,x)
  153. #else
  154. #define melde(x)
  155. #endif
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164. #define EREADBUF {if(READBUF < 1) error(E_READ);}
  165.  
  166. #define SKIP(n)  { if (fseek(fin,(n),1)) error(E_READ);}
  167. #define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
  168.  
  169.  
  170. #define xTRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b)  ))
  171. #define xNORM(x) x=TRIF(x,0,255,0,x,255)
  172. #define NORM(x) { if(x<0) x=0; else if (x>255) x=255;}
  173.  
  174.  
  175.  
  176.  
  177.  
  178. static void error(e)
  179.   enum ERRORS e;
  180.  {
  181.   
  182.   switch(e)
  183.    {case E_NONE:   return;
  184.     case E_IMP:    fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
  185.     case E_READ:   fprintf(stderr,"Error while reading.\n"); break;
  186.     case E_WRITE:  fprintf(stderr,"Error while writing.\n"); break;
  187.     case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
  188.     case E_ARG:    fprintf(stderr,"Error in Arguments !\n\n"); 
  189.                    fprintf(stderr,"Usage: hpcdtoppm [options] pcd-file [ppm-file]\n\n");
  190.                    fprintf(stderr,"Opts:\n");
  191.                    fprintf(stderr,"     -x Overskip mode (tries to improve color quality.)\n");
  192.                    fprintf(stderr,"     -i Give some (buggy) informations from fileheader\n");
  193.                    fprintf(stderr,"     -s Apply simple sharpness-operator on the Luma-channel\n");
  194.                    fprintf(stderr,"     -d Show differential picture only \n\n");
  195.                    fprintf(stderr,"     -r Rotate clockwise for portraits\n");
  196.                    fprintf(stderr,"     -l Rotate counter-clockwise for portraits\n");
  197.                    fprintf(stderr,"     -a Try to find out orientation automatically.\n");
  198.                    fprintf(stderr,"        (Experimentally, please report if it doesn't work.)\n\n");
  199.                    fprintf(stderr,"     -ycc suppress ycc to rgb conversion \n");
  200.                    fprintf(stderr,"        (Experimentally, doesn't have deeper sense)\n\n");
  201.                    fprintf(stderr,"     -0 Extract thumbnails from Overview file\n");
  202.                    fprintf(stderr,"     -1 Extract  128x192  from Image file\n");
  203.                    fprintf(stderr,"     -2 Extract  256x384  from Image file\n");
  204.                    fprintf(stderr,"     -3 Extract  512x768  from Image file\n");
  205.                    fprintf(stderr,"     -4 Extract 1024x1536 from Image file\n");
  206.                    fprintf(stderr,"     -5 Extract 2048x3072 from Image file\n");
  207.                    fprintf(stderr,"\n");
  208.                    break;
  209.     case E_OPT:    fprintf(stderr,"These Options are not allowed together.\n");break;
  210.     case E_MEM:    fprintf(stderr,"Not enough memory !\n"); break;
  211.     case E_HUFF:   fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
  212.     case E_SEQ:    fprintf(stderr,"Error in Huffman-Sequence\n"); break;
  213.     case E_SEQ1:   fprintf(stderr,"Error1 in Huffman-Sequence\n"); break;
  214.     case E_SEQ2:   fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
  215.     case E_SEQ3:   fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
  216.     case E_SEQ4:   fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
  217.     case E_SEQ5:   fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
  218.     case E_SEQ6:   fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
  219.     case E_SEQ7:   fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
  220.     case E_POS:    fprintf(stderr,"Error in file-position\n"); break;
  221.     case E_OVSKIP: fprintf(stderr,"Can't read this resolution in overskip-mode\n"); break;
  222.     case E_TAUTO:  fprintf(stderr,"Can't determine the orientation in overview mode\n");break;
  223.     case E_TCANT:  fprintf(stderr,"Sorry, can't determine orientation for this file.\n");
  224.                    fprintf(stderr,"Please give orientation parameters. \n");break;
  225.     default:       fprintf(stderr,"Unknown error %d ???\n",e);break;
  226.    }
  227.   if(fin) fclose(fin);
  228.   if(fout && ppmname) fclose(fout);
  229.   exit(9);
  230.  }
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240. static void planealloc(p,width,height)
  241.   implane *p;
  242.   dim width,height;
  243.  {
  244.   p->iwidth=p->iheight=0;
  245.   p->mwidth=width;
  246.   p->mheight=height;
  247.  
  248.   p->im = ( uBYTE * ) malloc  (width*height*sizeof(uBYTE));
  249.   if(!(p->im)) error(E_MEM);
  250.  }
  251.  
  252.  
  253.  
  254.  
  255.  
  256. void main(argc,argv)
  257.   int argc;
  258.   char **argv;
  259. #define ASKIP { argc--; argv ++;}
  260. {int bildnr;
  261.  char *opt;
  262.  dim w,h;
  263.  long cd_offset,cd_offhelp;
  264.  int do_info,do_diff,do_overskip;
  265.  
  266.  enum TURNS turn=T_NONE;
  267.  enum SIZES size=S_UNSPEC;
  268.  enum ERRORS eret;
  269.  implane Luma, Chroma1,Chroma2;
  270.  
  271.  do_info=do_diff=do_overskip=do_sharp=keep_ycc=0;
  272.  
  273.  ASKIP;
  274.  
  275.  while((argc>0) && **argv=='-')
  276.   {
  277.    opt= (*argv)+1;
  278.    ASKIP;
  279.  
  280.    if(!strcmp(opt,"r"))
  281.     {if (turn == T_NONE) turn=T_RIGHT;
  282.      else error(E_ARG);
  283.      continue;
  284.     }
  285.  
  286.    if(!strcmp(opt,"l"))
  287.     {if (turn == T_NONE) turn=T_LEFT;
  288.      else error(E_ARG);
  289.      continue;
  290.     }
  291.  
  292.     if(!strcmp(opt,"a"))
  293.     {if (turn == T_NONE) turn=T_AUTO;
  294.      else error(E_ARG);
  295.      continue;
  296.     }
  297.  
  298.    if(!strcmp(opt,"i")) 
  299.     { if (!do_info) do_info=1;
  300.       else error(E_ARG);
  301.       continue;
  302.     }
  303.  
  304.  
  305.    if(!strcmp(opt,"d")) 
  306.     { if (!do_diff) do_diff=1;
  307.       else error(E_ARG);
  308.       continue;
  309.     }
  310.  
  311.    if(!strcmp(opt,"s")) 
  312.     { if (!do_sharp) do_sharp=1;
  313.       else error(E_ARG);
  314.       continue;
  315.     }
  316.  
  317.  
  318.    if(!strcmp(opt,"x")) 
  319.     { if (!do_overskip) do_overskip=1;
  320.       else error(E_ARG);
  321.       continue;
  322.     }
  323.  
  324.  
  325.    if(!strcmp(opt,"ycc")) 
  326.     { if (!keep_ycc) keep_ycc=1;
  327.       else error(E_ARG);
  328.       continue;
  329.     }
  330.  
  331.  
  332.  
  333.    
  334.    if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  335.     { if (size == S_UNSPEC) size = S_Base16;
  336.       else error(E_ARG);
  337.       continue;
  338.     }
  339.    if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  340.     { if (size == S_UNSPEC) size = S_Base4;
  341.       else error(E_ARG);
  342.       continue;
  343.     }
  344.    if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  345.     { if (size == S_UNSPEC) size = S_Base;
  346.       else error(E_ARG);
  347.       continue;
  348.     }
  349.    if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  350.     { if (size == S_UNSPEC) size = S_4Base;
  351.       else error(E_ARG);
  352.       continue;
  353.     }
  354.    if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  355.     { if (size == S_UNSPEC) size = S_16Base;
  356.       else error(E_ARG);
  357.       continue;
  358.     }
  359.  
  360.    if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0"))  || (!strcmp(opt,"O")))
  361.     { if (size == S_UNSPEC) size = S_Over;
  362.       else error(E_ARG);
  363.       continue;
  364.     }
  365.  
  366.   fprintf(stderr,"Unknown option: -%s\n",opt);
  367.   error(E_ARG);
  368.   }
  369.  
  370.  
  371.  
  372.  
  373.   if(size==S_UNSPEC) size=S_DEFAULT;
  374.  
  375.   if(argc<1) error(E_ARG);
  376.   pcdname= *argv;
  377.   ASKIP;
  378.  
  379.   if(argc>0) 
  380.    {ppmname= *argv;
  381.     ASKIP;
  382.    }
  383.   
  384.   if(argc>0) error(E_ARG);
  385.   if((size==S_Over) && (!ppmname)) error(E_ARG);
  386.   if(do_info && (size==S_Over)) error(E_OPT);
  387.   if(do_overskip && do_diff) error(E_OPT);
  388.   if(do_diff && (size != S_4Base) && (size != S_16Base)) error(E_OPT);
  389.   if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP);
  390.   if((turn==T_AUTO)&&(size==S_Over)) error(E_TAUTO);
  391.   
  392.  
  393.  
  394.  
  395.  
  396.   if(!(fin=fopen(pcdname,"r"))) error(E_READ);
  397.  
  398.   if(do_info || (turn==T_AUTO)) 
  399.    { SEEK(1);
  400.      EREADBUF;
  401.    }
  402.  
  403.   if(turn==T_AUTO)
  404.    {
  405.     switch(sbuffer[0xe02 & 0x7ff]&0x03)
  406.      {case 0x00: turn=T_NONE;  break;
  407.       case 0x01: turn=T_LEFT;  break;
  408.       case 0x03: turn=T_RIGHT; break;
  409.       default: error(E_TCANT);
  410.      }
  411.    }
  412.  
  413.   if(do_info) druckeid();
  414.  
  415.  
  416.  
  417.  
  418.  
  419.   switch(size)
  420.    {
  421.     case S_Base16: w=BaseW/4;
  422.                    h=BaseH/4;
  423.                    planealloc(&Luma   ,w,h);
  424.                    planealloc(&Chroma1,w,h);
  425.                    planealloc(&Chroma2,w,h);
  426.  
  427.                    if(!do_overskip)
  428.                      { SEEK(L_Head+1);
  429.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  430.                        interpolate(&Chroma1);
  431.                        interpolate(&Chroma2);
  432.                      }
  433.                    else
  434.                      { SEEK(L_Head+1);
  435.                        error(readplain(w,h,&Luma,nullplane,nullplane));
  436.                        SEEK(L_Head+L_Base16+1);
  437.                        error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  438.                      }
  439.                     
  440.  
  441.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  442.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  443.  
  444.                    if(!ppmname) fout=stdout;
  445.                    else
  446.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  447.             }
  448.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  449.  
  450.                    break;
  451.  
  452.     case S_Base4:  w=BaseW/2;
  453.                    h=BaseH/2;
  454.                    planealloc(&Luma   ,w,h);
  455.                    planealloc(&Chroma1,w,h);
  456.                    planealloc(&Chroma2,w,h);
  457.  
  458.  
  459.  
  460.                   if(!do_overskip)
  461.                      { SEEK(L_Head+L_Base16+1);
  462.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  463.                        interpolate(&Chroma1);
  464.                        interpolate(&Chroma2);
  465.                      }
  466.                    else
  467.                      { SEEK(L_Head+L_Base16+1);
  468.                        error(readplain(w,h,&Luma,nullplane,nullplane));
  469.                        SEEK(L_Head+L_Base16+L_Base4+1); 
  470.                        error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  471.                      }
  472.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  473.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  474.  
  475.                    if(!ppmname) fout=stdout;
  476.                    else
  477.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  478.             }
  479.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  480.  
  481.                    break;
  482.  
  483.     case S_Base:   w=BaseW;
  484.                    h=BaseH;
  485.  
  486.                    if(!do_overskip)
  487.                      { planealloc(&Luma   ,w,h);
  488.                        planealloc(&Chroma1,w,h);
  489.                        planealloc(&Chroma2,w,h);
  490.                        SEEK(L_Head+L_Base16+L_Base4+1);
  491.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  492.                        interpolate(&Chroma1);
  493.                        interpolate(&Chroma2);
  494.                      }
  495.                    else
  496.                      { planealloc(&Luma   ,  w,  h);
  497.                        planealloc(&Chroma1,2*w,2*h);
  498.                        planealloc(&Chroma2,2*w,2*h);
  499.                        SEEK(L_Head+L_Base16+L_Base4+1);
  500.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  501.                        interpolate(&Chroma1);
  502.                        interpolate(&Chroma2);
  503.                        interpolate(&Chroma1);
  504.                        interpolate(&Chroma2);
  505.  
  506.                        cd_offset=Skip4Base();
  507.                        SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  508.                        SEEK(cd_offset+12);          readhqt(w,h,3);
  509.                        SEEK(cd_offset+cd_offhelp);  decode(4*w,4*h,nullplane,&Chroma1,&Chroma2,1);
  510.  
  511.                        halve(&Chroma1);
  512.                        halve(&Chroma2);
  513.                      }
  514.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  515.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  516.  
  517.                    if(!ppmname) fout=stdout;
  518.                    else
  519.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  520.             }
  521.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  522.  
  523.                    break;
  524.  
  525.     case S_4Base:  w=BaseW*2;
  526.                    h=BaseH*2;
  527.                    planealloc(&Luma,w,h);
  528.                    planealloc(&Chroma1,w,h);
  529.                    planealloc(&Chroma2,w,h);
  530.  
  531.                   if(!do_overskip)
  532.                      {SEEK(L_Head+L_Base16+L_Base4+1);
  533.                       error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  534.                       interpolate(&Luma);
  535.                       interpolate(&Chroma1);
  536.                       interpolate(&Chroma1);
  537.                       interpolate(&Chroma2);
  538.                       interpolate(&Chroma2);
  539.  
  540.                       if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  541.  
  542.                       cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  543.                       SEEK(cd_offset + 4);     readhqt(w,h,1);
  544.                       SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  545.                      }
  546.                    else
  547.                      {SEEK(L_Head+L_Base16+L_Base4+1);
  548.                       error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  549.                       interpolate(&Luma);
  550.                       interpolate(&Chroma1);
  551.                       interpolate(&Chroma1);
  552.                       interpolate(&Chroma2);
  553.                       interpolate(&Chroma2);
  554.  
  555.                       cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  556.                       SEEK(cd_offset + 4);     readhqt(w,h,1);
  557.                       SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  558.  
  559.                       cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  560.                       SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  561.                       SEEK(cd_offset+12);          readhqt(w,h,3);
  562.                       SEEK(cd_offset+cd_offhelp);  decode(2*w,2*h,nullplane,&Chroma1,&Chroma2,1);
  563.                      
  564.                      }
  565.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  566.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  567.  
  568.                    if(!ppmname) fout=stdout;
  569.                    else
  570.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  571.             }
  572.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  573.  
  574.                    break;
  575.  
  576.     case S_16Base: w=BaseW*4;
  577.                    h=BaseH*4;
  578.                    planealloc(&Luma,w,h);
  579.                    planealloc(&Chroma1,w,h);
  580.                    planealloc(&Chroma2,w,h);
  581.  
  582.                    SEEK(L_Head+L_Base16+L_Base4+1);
  583.                    error(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
  584.                    interpolate(&Luma);
  585.                    interpolate(&Chroma1);
  586.                    interpolate(&Chroma1);
  587.                    interpolate(&Chroma2);
  588.                    interpolate(&Chroma2);
  589.  
  590.                    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  591.                    SEEK(cd_offset + 4);       readhqt(w/2,h/2,1);
  592.                    SEEK(cd_offset + 5);       decode(w/2,h/2,&Luma,nullplane,nullplane,0);
  593.                    interpolate(&Luma);
  594.  
  595.                    if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  596.  
  597.                    cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  598.  
  599.                    SEEK(cd_offset+12);        readhqt(w,h,3);
  600.                    SEEK(cd_offset+14);        decode(w,h,&Luma,&Chroma1,&Chroma2,0);
  601.  
  602.                    interpolate(&Chroma1);
  603.                    interpolate(&Chroma2);
  604.  
  605.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  606.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  607.  
  608.                    if(!ppmname) fout=stdout;
  609.                    else
  610.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  611.             }
  612.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  613.  
  614.                    break;
  615.  
  616.     case S_Over:   w=BaseW/4;
  617.                    h=BaseH/4;
  618.              
  619.                    planealloc(&Luma   ,w,h);
  620.                    planealloc(&Chroma1,w,h);
  621.                    planealloc(&Chroma2,w,h);
  622.  
  623.                    for(bildnr=0;!feof(fin);bildnr++)
  624.             {
  625.                SEEK(5+SeBase16*bildnr);
  626.     
  627.                eret=readplain(w,h,&Luma,&Chroma1,&Chroma2);
  628.                        if(eret==E_READ) break;
  629.                        error(eret);
  630.  
  631.                interpolate(&Chroma1);
  632.                interpolate(&Chroma2);
  633.     
  634.                ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  635.                /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  636.     
  637.                        sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
  638.                if (!(fout=fopen(nbuf,"w"))) error(E_WRITE);
  639.                writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  640.              }
  641.                    break;
  642.  
  643.      default: error(E_INTERN); 
  644.    }
  645.  
  646.  
  647.  
  648.  
  649. exit(0);
  650.  
  651.  
  652.  
  653. }
  654. #undef ASKIP
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661. static enum ERRORS readplain(w,h,l,c1,c2)
  662.   dim w,h;
  663.   implane *l,*c1,*c2;
  664.  {dim i;
  665.   uBYTE *pl=0,*pc1=0,*pc2=0;
  666.   melde("readplain\n");
  667.  
  668.   if(l)
  669.    { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
  670.      l->iwidth=w;
  671.      l->iheight=h;
  672.      pl=l->im;
  673.    }
  674.  
  675.   if(c1)
  676.    { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
  677.      c1->iwidth=w/2;
  678.      c1->iheight=h/2;
  679.      pc1=c1->im;
  680.    }
  681.  
  682.   if(c2)
  683.    { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
  684.      c2->iwidth=w/2;
  685.      c2->iheight=h/2;
  686.      pc2=c2->im;
  687.    }
  688.  
  689.   for(i=0;i<h/2;i++)
  690.    {
  691.     if(pl)
  692.      { 
  693.        if(fread(pl,w,1,fin)<1) return(E_READ);
  694.        pl+= l->mwidth;
  695.  
  696.        if(fread(pl,w,1,fin)<1) return(E_READ);
  697.        pl+= l->mwidth;
  698.      }
  699.     else SKIPr(2*w);
  700.      
  701.     if(pc1)
  702.      { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
  703.        pc1+= c1->mwidth;
  704.      }
  705.     else SKIPr(w/2);
  706.      
  707.     if(pc2)
  708.      { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
  709.        pc2+= c2->mwidth;
  710.      }
  711.     else SKIPr(w/2);
  712.  
  713.  
  714.    }
  715.   RPRINT;
  716.   return E_NONE;
  717.  }
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729. static void interpolate(p)
  730.   implane *p;
  731.  {dim w,h,x,y,yi;
  732.   uBYTE *optr,*nptr,*uptr;
  733.  
  734.   melde("interpolate\n");
  735.   if ((!p) || (!p->im)) error(E_INTERN);
  736.  
  737.   w=p->iwidth;
  738.   h=p->iheight;
  739.  
  740.   if(p->mwidth  < 2*w ) error(E_INTERN);
  741.   if(p->mheight < 2*h ) error(E_INTERN);
  742.  
  743.  
  744.   p->iwidth=2*w;
  745.   p->iheight=2*h;
  746.  
  747.  
  748.   for(y=0;y<h;y++)
  749.    {yi=h-1-y;
  750.     optr=p->im+  yi*p->mwidth + (w-1);
  751.     nptr=p->im+2*yi*p->mwidth + (2*w - 2);
  752.  
  753.     nptr[0]=nptr[1]=optr[0];
  754.  
  755.     for(x=1;x<w;x++)
  756.      { optr--; nptr-=2;
  757.        nptr[0]=optr[0];
  758.        nptr[1]=(((int)optr[0])+((int)optr[1])+1)>>1;
  759.      }
  760.     }
  761.  
  762.   for(y=0;y<h-1;y++)
  763.    {optr=p->im + 2*y*p->mwidth;
  764.     nptr=optr+p->mwidth;
  765.     uptr=nptr+p->mwidth;
  766.  
  767.     for(x=0;x<w-1;x++)
  768.      {
  769.       nptr[0]=(((int)optr[0])+((int)uptr[0])+1)>>1;
  770.       nptr[1]=(((int)optr[0])+((int)optr[2])+((int)uptr[0])+((int)uptr[2])+2)>>2;
  771.       nptr+=2; optr+=2; uptr+=2;
  772.      }
  773.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  774.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  775.    }
  776.  
  777.  
  778.   optr=p->im + (2*h-2)*p->mwidth;
  779.   nptr=p->im + (2*h-1)*p->mwidth;
  780.   for(x=0;x<w;x++)
  781.    { *(nptr++) = *(optr++);  *(nptr++) = *(optr++); }
  782.  
  783.  }
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794. static void halve(p)
  795.   implane *p;
  796.  {dim w,h,x,y;
  797.   uBYTE *optr,*nptr;
  798.  
  799.   melde("halve\n");
  800.   if ((!p) || (!p->im)) error(E_INTERN);
  801.  
  802.   w=p->iwidth/=2;      
  803.   h=p->iheight/=2;     
  804.  
  805.  
  806.   for(y=0;y<h;y++)
  807.    {
  808.     nptr=(p->im) +   y*(p->mwidth);
  809.     optr=(p->im) + 2*y*(p->mwidth);
  810.  
  811.     for(x=0;x<w;x++,nptr++,optr+=2)
  812.      { *nptr = *optr;
  813.      }
  814.  
  815.    }
  816.  
  817.  }
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829. #define BitShift 12
  830.  
  831. static void ycctorgb(w,h,l,c1,c2)
  832.   dim w,h;
  833.   implane *l,*c1,*c2;
  834.  {dim x,y;
  835.   uBYTE *pl,*pc1,*pc2;
  836.   long red,green,blue,i;
  837.   long L;
  838.   static int init=0;
  839.   static long XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
  840.  
  841.   melde("ycctorgb\n");
  842.   if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) error(E_INTERN);
  843.   if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) error(E_INTERN);
  844.   if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) error(E_INTERN);
  845.  
  846.   if(do_sharp) sharpit(l);
  847.   if(keep_ycc) return;
  848.  
  849.   if(!init)
  850.    {init=1;
  851.     for(i=0;i<256;i++)
  852.      {  XL[i]= 5564 * i + 2048;
  853.        XC1[i]= 9085 * i - 1417185;
  854.        XC2[i]= 7461 * i - 1022138;
  855.       XC1g[i]= 274934 - 1762 * i;
  856.       XC2g[i]= 520268 - 3798 * i; 
  857.      }
  858.    }
  859.  
  860.   for(y=0;y<h;y++)
  861.    {
  862.     pl =  l->im + y *  l->mwidth;
  863.     pc1= c1->im + y * c1->mwidth;
  864.     pc2= c2->im + y * c2->mwidth;
  865.  
  866.     for(x=0;x<w;x++)
  867.      {
  868.       L = XL[*pl]; 
  869.       red  =(L + XC2[*pc2]               )>>BitShift;
  870.       green=(L + XC1g[*pc1] + XC2g[*pc2] )>>BitShift; 
  871.       blue =(L + XC1[*pc1]               )>>BitShift;
  872.  
  873.       NORM(red);
  874.       NORM(green);
  875.       NORM(blue);
  876.  
  877.       *(pl++ )=red; 
  878.       *(pc1++)=green; 
  879.       *(pc2++)=blue;
  880.      }
  881.    }
  882.  }
  883. #undef BitShift
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890. static void writepicture(w,h,r,g,b,t)
  891.   dim w,h;
  892.   implane *r,*g,*b;
  893.   enum TURNS t;
  894.  {dim x,y;
  895.   register uBYTE *pr,*pg,*pb;
  896. #ifndef OWN_WRITE
  897.   pixel *pixrow;
  898.   register pixel* pP;
  899. #else
  900.   static uBYTE BUF[own_BUsize],*BUptr;
  901.   int   BUcount;
  902.  
  903. #define BUinit {BUcount=0;BUptr=BUF;}
  904. #define BUflush {fwrite(BUF,BUcount*3,1,fout);BUinit; }
  905. #define BUwrite(r,g,b) {if(BUcount>=own_BUsize/3) BUflush; *BUptr++ = r ; *BUptr++ = g ; *BUptr++ = b ; BUcount++;}
  906.  
  907. #endif
  908.  
  909.   melde("writepicture\n");
  910.   if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
  911.   if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
  912.   if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
  913.  
  914.   switch (t)
  915.    { case T_NONE:
  916. #ifndef OWN_WRITE
  917.               ppm_writeppminit(fout,w,h,(pixval) 255, 0);
  918.               pixrow = ppm_allocrow( w );
  919.           for(y=0;y<h;y++)
  920.            {
  921.         pr= r->im + y * r->mwidth;
  922.         pg= g->im + y * g->mwidth;
  923.         pb= b->im + y * b->mwidth;
  924.         
  925.              for(pP= pixrow,x=0;x<w;x++)
  926.          {
  927.           PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  928.           pP++;  pr++;  pg++;  pb++;
  929.          }
  930.         ppm_writeppmrow( fout, pixrow, w, (pixval) 255, 0 );
  931.         
  932.            }
  933.           pm_close(fout);
  934. #else
  935.               fprintf(fout,PPM_Header,w,h);
  936.               BUinit;
  937.           for(y=0;y<h;y++)
  938.            {
  939.         pr= r->im + y * r->mwidth;
  940.         pg= g->im + y * g->mwidth;
  941.         pb= b->im + y * b->mwidth;
  942.         
  943.              for(x=0;x<w;x++) BUwrite(*pr++,*pg++,*pb++);        
  944.            }
  945.               BUflush;
  946.               if(ppmname) fclose(fout);
  947. #endif
  948.               break;
  949.      case T_RIGHT:
  950. #ifndef OWN_WRITE
  951.               ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  952.               pixrow = ppm_allocrow( h );
  953.  
  954.           for(y=0;y<w;y++)
  955.            {
  956.         pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  957.         pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  958.         pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  959.         
  960.         for(pP= pixrow,x=0;x<h;x++)
  961.          {
  962.           PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  963.           pP++;      pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  964.          }
  965.         ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  966.         
  967.            }
  968.           pm_close(fout);
  969. #else
  970.               fprintf(fout,PPM_Header,h,w);
  971.               BUinit;
  972.           for(y=0;y<w;y++)
  973.            {
  974.         pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  975.         pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  976.         pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  977.         
  978.              for(x=0;x<h;x++) 
  979.                 {BUwrite(*pr,*pg,*pb);    
  980.          pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  981.                 }    
  982.            }
  983.               BUflush;
  984.               if(ppmname) fclose(fout);
  985. #endif
  986.               break;
  987.  
  988.       case T_LEFT:
  989. #ifndef OWN_WRITE
  990.               ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  991.               pixrow = ppm_allocrow( h );
  992.  
  993.           for(y=0;y<w;y++)
  994.            {
  995.         pr= r->im + r->iwidth - 1 - y;
  996.         pg= g->im + g->iwidth - 1 - y;
  997.         pb= b->im + b->iwidth - 1 - y;
  998.         
  999.         
  1000.         
  1001.         for(pP= pixrow,x=0;x<h;x++)
  1002.          {
  1003.           PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1004.           pP++;      pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1005.          }
  1006.         ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  1007.         
  1008.            }
  1009.           pm_close(fout);
  1010. #else
  1011.               fprintf(fout,PPM_Header,h,w);
  1012.               BUinit;
  1013.           for(y=0;y<w;y++)
  1014.            {
  1015.         pr= r->im + r->iwidth - 1 - y;
  1016.         pg= g->im + g->iwidth - 1 - y;
  1017.         pb= b->im + b->iwidth - 1 - y;
  1018.         
  1019.              for(x=0;x<h;x++) 
  1020.                 {BUwrite(*pr,*pg,*pb);    
  1021.          pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1022.                 }    
  1023.            }
  1024.               BUflush;
  1025.               if(ppmname) fclose(fout);
  1026.  
  1027. #endif
  1028.               break;
  1029.       default: error(E_INTERN);
  1030.     }
  1031.  }
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052. struct ph1 
  1053.  {char  id1[8];
  1054.   uBYTE ww1[14];
  1055.   char  id2[20];
  1056.   char  id3[4*16+4];
  1057.   short ww2;
  1058.   char  id4[20];
  1059.   uBYTE ww3[2*16+1];
  1060.   char  id5[4*16];
  1061.   uBYTE idx[11*16];
  1062.  } ;
  1063.  
  1064.  
  1065. static void druckeid()
  1066. {int i;
  1067.  struct ph1 *d;
  1068.  char ss[100];
  1069.  
  1070.  d=(struct ph1 *)sbuffer;
  1071.  
  1072. #define dr(feld,kennung)   \
  1073.      strncpy(ss,feld,sizeof(feld));\
  1074.      ss[sizeof(feld)]=0;\
  1075.      fprintf(stderr,"%s: %s \n",kennung,ss);
  1076.  
  1077. #define db(feld) fprintf(stderr,"--%d\n",sizeof(feld)); for(i=0;i<sizeof(feld);i+=2) \
  1078.   fprintf(stderr,"%4d %6d\n",i,(signed int)((((unsigned int)feld[i])<<8)|feld[i+1]));\
  1079.   fprintf(stderr,"\n");
  1080.  
  1081. dr(d->id1,"Id1")
  1082. dr(d->id2,"Id2")
  1083. dr(d->id3,"Id3")
  1084. dr(d->id4,"Id4")
  1085. dr(d->id5,"Id5")
  1086.  
  1087. /*
  1088. db(d->ww1)
  1089. db(d->ww3)
  1090. db(d->idx)
  1091. */
  1092.  
  1093. #undef dr 
  1094. #undef db
  1095.  
  1096. }
  1097.  
  1098.  
  1099.  
  1100. struct pcdword
  1101.  { uBYTE high,low;
  1102.  };
  1103.  
  1104. static int lpt[1024];
  1105.  
  1106. static void readlpt(w,h)
  1107.   dim w,h;
  1108.  {int i;
  1109.   struct pcdword *ptr;
  1110.  
  1111.   EREADBUF;
  1112.  
  1113.   ptr = (struct pcdword *)sbuffer;
  1114.  
  1115.   for(i=0;i<h/4;i++,ptr++)
  1116.    {lpt[i] = ((int)ptr->high)<<8 | ptr->low ;
  1117.    }
  1118.  
  1119.  
  1120.   
  1121.  }
  1122.  
  1123.  
  1124.  
  1125. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  1126. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  1127. struct myhqt { unsigned long seq,mask,len; uBYTE key; };
  1128.  
  1129.  
  1130. #define E ((unsigned long) 1)
  1131.  
  1132.  
  1133. static void readhqtsub(source,ziel,anzahl)
  1134.   struct pcdhqt *source;
  1135.   struct myhqt *ziel;
  1136.   int *anzahl;
  1137.  {int i;
  1138.   struct pcdquad *sub;
  1139.   struct myhqt *help;
  1140.   *anzahl=(source->entries)+1;
  1141.  
  1142.   for(i=0;i<*anzahl;i++)
  1143.    {sub = (struct pcdquad *)(((uBYTE *)source)+1+i*sizeof(*sub));
  1144.     help=ziel+i;
  1145.  
  1146.     help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  1147.     help->len = ((unsigned long) sub->len) +1;
  1148.     help->key = sub->key;
  1149.  
  1150. #ifdef DEBUGhuff
  1151.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  1152.           *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  1153.           help->seq,help->len,sizeof(uBYTE));
  1154. #endif
  1155.  
  1156.     if(help->len > 16) error(E_HUFF);
  1157.  
  1158.     help->mask = ~ ( (E << (32-help->len)) -1); 
  1159.  
  1160.   }
  1161. #ifdef DEBUG
  1162.   for(i=0;i<*anzahl;i++)
  1163.    {help=ziel+i;
  1164.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  1165.         i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  1166.         help->seq & (~help->mask));
  1167.    }
  1168. #endif
  1169.  
  1170. }
  1171.  
  1172. #undef E
  1173.  
  1174. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  1175. static int          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  1176.  
  1177. static void readhqt(w,h,n)
  1178.   dim w,h;
  1179.   int n;
  1180.  {
  1181.   uBYTE *ptr;
  1182.  
  1183.   melde("readhqt\n");
  1184.   EREADBUF;
  1185.   ptr = sbuffer;
  1186.  
  1187.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  1188.  
  1189.   if(n<2) return;
  1190.   ptr+= 1 + 4* myhufflen0;
  1191.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  1192.  
  1193.   if(n<3) return;
  1194.   ptr+= 1 + 4* myhufflen1;
  1195.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  1196.  
  1197. }
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203. static void decode(w,h,f,f1,f2,autosync)
  1204.   dim w,h;
  1205.   implane *f,*f1,*f2;
  1206.   int autosync;
  1207.  {int i,htlen,sum;
  1208.   unsigned long sreg,maxwidth;
  1209.   unsigned int inh,n,zeile,segment,ident;
  1210.   struct myhqt *htptr,*hp;
  1211.  
  1212.   uBYTE *nptr;
  1213.   uBYTE *lptr;
  1214.  
  1215.   melde("decode\n");
  1216. #define nextbuf  {  nptr=sbuffer;  EREADBUF; }
  1217. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  1218. #define shiftout(n){ sreg<<=n; inh-=n; \
  1219.                      while (inh<=24) \
  1220.                       {checkbuf; \
  1221.                        sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  1222.                        inh+=8;\
  1223.                       }\
  1224.                     }  
  1225. #define issync ((sreg & 0xffffff00) == 0xfffffe00) 
  1226. #define seeksync { while (!issync) shiftout(1);}
  1227.  
  1228.  
  1229.   if( f  && ((! f->im) || ( f->iheight < h  ) ||  (f->iwidth<w  ))) error(E_INTERN);
  1230.   if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
  1231.   if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);
  1232.  
  1233.   htlen=sreg=maxwidth=0;
  1234.   htptr=0;
  1235.   nextbuf;
  1236.   inh=32;
  1237.   lptr=0;
  1238.   shiftout(16);
  1239.   shiftout(16);
  1240.  
  1241.   if(autosync) seeksync;
  1242.  
  1243.   n=0;
  1244.   for(;;)
  1245.    {
  1246.     if (issync)
  1247.      {shiftout(24);
  1248.       ident=sreg>>16;
  1249.       shiftout(16);
  1250.  
  1251.       zeile=(ident>>1) & 0x1fff;
  1252.       segment=ident>>14;
  1253.  
  1254. #ifdef DEBUG
  1255.       fprintf(stderr,"Ident %4x Zeile:  %6d  Segment %3d Pixels bisher: %5d   Position: %8lx\n",
  1256.           ident,zeile,segment,n,bufpos);
  1257. #endif
  1258.  
  1259.  
  1260.       if(lptr && (n!=maxwidth)) error(E_SEQ1);
  1261.       n=0;
  1262.  
  1263.       if(zeile==h) {RPRINT; return; }
  1264.       if(zeile >h) error(E_SEQ2);
  1265.  
  1266.       switch(segment)
  1267.        {
  1268.         case 0: if((!f) && autosync) {seeksync; break;}
  1269.                 if(!f) error(E_SEQ7);
  1270.                 lptr=f->im + zeile*f->mwidth;
  1271.                 maxwidth=f->iwidth;
  1272.                 htlen=myhufflen0;
  1273.                 htptr=myhuff0;
  1274.                 break;
  1275.  
  1276.         case 2: if((!f1) && autosync) {seeksync; break;}
  1277.                 if(!f1) error(E_SEQ7);
  1278.                 lptr=f1->im + (zeile>>1)*f1->mwidth;
  1279.                 maxwidth=f1->iwidth;
  1280.                 htlen=myhufflen1;
  1281.                 htptr=myhuff1;
  1282.                 break;
  1283.  
  1284.         case 3: if((!f2) && autosync) {seeksync; break;}
  1285.                 if(!f2) error(E_SEQ7);
  1286.                 lptr=f2->im + (zeile>>1)*f2->mwidth;
  1287.                 maxwidth=f2->iwidth;
  1288.                 htlen=myhufflen2;
  1289.                 htptr=myhuff2;
  1290.                 break;
  1291.  
  1292.         default:error(E_SEQ3);
  1293.     }
  1294.      }
  1295.     else
  1296.      {
  1297. /*      if((!lptr) || (n>maxwidth)) error(E_SEQ4);*/
  1298.       if(!lptr)      error(E_SEQ6);
  1299.       if(n>maxwidth) error(E_SEQ4);
  1300.       for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
  1301.       if(i>=htlen) error(E_SEQ5);
  1302.  
  1303.       sum=((int)(*lptr)) + ((sBYTE)hp->key);
  1304.       NORM(sum);
  1305.       *(lptr++) = sum;
  1306.  
  1307.       n++; 
  1308.       shiftout(hp->len);
  1309.  
  1310.      }
  1311.  
  1312.    }
  1313.  
  1314.  
  1315. #undef nextbuf  
  1316. #undef checkbuf 
  1317. #undef shiftout
  1318. #undef issync
  1319. #undef seeksync
  1320.  
  1321.  }
  1322.  
  1323.  
  1324.  
  1325.  
  1326. static void clear(l,n)
  1327.   implane *l;
  1328.   int n;
  1329. { dim x,y;
  1330.   uBYTE *ptr;
  1331.  
  1332.   ptr=l->im;
  1333.   for (x=0;x<l->mwidth;x++)
  1334.     for (y=0; y<l->mheight;y++)
  1335.       *(ptr++)=n;
  1336. }
  1337.  
  1338.  
  1339.  
  1340. #define slen 3072
  1341.  
  1342. static void sharpit(l)
  1343.   implane *l;
  1344.  {int x,y,h,w,mw,akk;
  1345.   uBYTE f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
  1346.  
  1347.   if((!l) || (!l->im)) error(E_INTERN);
  1348.   if(l->iwidth > slen) error(E_INTERN);
  1349.  
  1350.   old=f1; akt=f2;
  1351.   h=l->iheight;
  1352.   w=l->iwidth;
  1353.   mw=l->mwidth;
  1354.  
  1355.   for(y=1;y<h-1;y++)
  1356.    {
  1357.     ptr=l->im+ y*mw;
  1358.     optr=ptr-mw;
  1359.     work=akt;
  1360.  
  1361.     *(work++)= *(ptr++);
  1362.     for(x=1;x<w-1;x++)
  1363.      {  akk = 5*((int)ptr[0])- ((int)ptr[1])  - ((int)ptr[-1]) 
  1364.                               - ((int)ptr[mw]) - ((int)ptr[-mw]);
  1365.         NORM(akk);
  1366.         *(work++)=akk;
  1367.         ptr++;
  1368.      }
  1369.  
  1370.     *(work++)= *(ptr++);
  1371.  
  1372.     if(y>1) bcopy(old,optr,w);
  1373.     help=old;old=akt;akt=help;
  1374.      
  1375.    }
  1376.  
  1377.  
  1378.  
  1379.   akt=optr+mw;
  1380.   for(x=0;x<w;x++)
  1381.     *(akt++) = *(old++);
  1382.  }
  1383.  
  1384.  
  1385. #undef slen
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392. static int testbegin()
  1393.  {int i,j;
  1394.   for(i=j=0;i<32;i++)
  1395.     if(sbuffer[i]==0xff) j++;
  1396.  
  1397.   return (j>30);
  1398.   
  1399.  }
  1400.  
  1401. static long Skip4Base()
  1402.   {long cd_offset,cd_offhelp;
  1403.    
  1404.    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  1405.    SEEK(cd_offset+3);          
  1406.    EREADBUF;    
  1407.    cd_offhelp=(((long)sbuffer[510])<<8)|sbuffer[511] + 1;
  1408.  
  1409.    cd_offset+=cd_offhelp;
  1410.  
  1411.    SEEK(cd_offset);
  1412.    EREADBUF;
  1413.    while(!testbegin())
  1414.     {cd_offset++;
  1415.      EREADBUF;
  1416.     }
  1417.    return cd_offset;
  1418.   }
  1419.